package cn.itsub.sodo.action;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import cn.itsub.sodo.Node;
import cn.itsub.sodo.action.base.Action;
import cn.itsub.sodo.timer.HiScheduler;
import cn.itsub.sodo.timer.UpdateCallback;

public class ActionManager {
	static{

		HiScheduler.getInstance().scheduleUpdate(new UpdateCallback() {
			
			@Override
			public void update(float dt) {
				ActionManager.update(dt);
			}
		}, 0, false);
	}
	public static class Element{
		final List<Action> actions = new ArrayList<Action>();
		Node target = null;		//执行动作的目标
		boolean paused = false;	//Node的动作是否暂停
		int actionIndex = -1;	//正在处理Node的第几个动作
	}
	//记录Node与Element的关系
	private static Map<Node, Element> NodeElementMap = new ConcurrentHashMap<Node, ActionManager.Element>();
	

	private static void removeElement(Element element){
		System.out.println(element);
		synchronized (element.actions) {
			element.actions.clear();
		}
		element.actionIndex = -1;
		NodeElementMap.remove(element.target);
	}
	private static void removeActionFromElement(Element element,int index){
		synchronized (element.actions) {
			element.actions.remove(index);
			if(element.actionIndex>=index){
				element.actionIndex--;
			}
			if(element.actions.isEmpty()){
				removeElement(element);
			}
		}
	}
	/**
	 * 向Node中添加动作
	 * @param action
	 * @param target
	 * @param paused
	 */
	public static void addAction(Action action,Node target,boolean paused){
		Element element = NodeElementMap.get(target);
		if(element==null){
			element = new Element();
			element.paused = paused;
			element.target = target;
			NodeElementMap.put(target, element);
		}
		synchronized (target) {
			if(!element.actions.contains(action)){
				element.actions.add(action);
			}
		}
		action.start(target);
	}
	/**
	 * 移除全部动作
	 */
	public static void removeAllActions(){
		for(Entry<Node, Element> e : NodeElementMap.entrySet()){
			Element el = e.getValue();
			if(el!=null){
				removeElement(el);
			}
		}
	}
	/**
	 * 移除指定节点的全部动作
	 * @param target
	 */
	public static void removeAllActions(Node target){
		if(target==null)return;
		Element el = NodeElementMap.get(target);
		if(el!=null){
			removeElement(el);
		}
	}
	/**
	 * 移除Action
	 * @param action
	 */
	public static void removeAction(Action action){
		if(action==null)return;
		Element element = NodeElementMap.get(action.getTarget());
		if(element!=null){
			int index = element.actions.indexOf(action);
			removeActionFromElement(element, index);
		}
	}
	/**
	 * 移除Action
	 * @param action
	 */
	public static void removeAction(Node target,String tag){
		Element element = NodeElementMap.get(target);
		if(element!=null){
			synchronized (element.actions) {
				for(int i=0;i<element.actions.size();i++){
					Action act = element.actions.get(i);
					if(act.getTag()!=null&&act.getTag().equals(tag)){
						removeActionFromElement(element, i);
						break;
					}
				}
			}
		}
	}
	public static Action getAction(Node target,String tag){
		Element element = NodeElementMap.get(target);
		if(element!=null){
			synchronized (element.actions) {
				for(int i=0;i<element.actions.size();i++){
					Action act = element.actions.get(i);
					if(act.getTag()!=null&&act.getTag().equals(tag)){
						return act;
					}
				}
				
			}
		}
		return null;
	}
	public static void resume(Node target) {
		Element element = NodeElementMap.get(target);
		if (element != null)
			element.paused = false;
	}

	public static void pause(Node target) {
		Element element = NodeElementMap.get(target);
    	if( element != null )
	    	element.paused = true;
	}
	public static void update(float dt){
		Iterator<Entry<Node, Element>> it = NodeElementMap.entrySet().iterator();
		while(it.hasNext()){
			Entry<Node, Element> e = it.next();
			Element element = e.getValue();
			if(element==null)continue;
			if(!element.paused){
				synchronized (element.actions) {
					for(element.actionIndex=0;element.actionIndex<element.actions.size();element.actionIndex++){
						Action action = element.actions.get(element.actionIndex);
						action.step(dt);
						if(action.isDone()){
							action.stop();
							if(NodeElementMap.get(element.target)!=null&&element.actionIndex>=0){
								removeActionFromElement(element, element.actionIndex);
							}
						}
					}
					element.actionIndex = -1;
				}
			}
			if(element.actions.isEmpty()){
				removeElement(element);
			}
		}
		
	}
}
